package top.milkbox.log.core.aop;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import top.milkbox.log.modular.main.service.LogMainService;

/**
 * 日志注解的切点处理
 * 创建时间: 2024-01-19 下午 2:01
 *
 * @author milkbox
 */
@Slf4j
@Aspect
@Component
@AllArgsConstructor
public class LogAop {

    private LogMainService logMainService;

    /**
     * 抽取切点，抽取所有被注解CommonLog修饰的方法
     */
    @Pointcut("@annotation(top.milkbox.common.annotation.CommonLog)")
    public void logPointcut() {
    }

    /**
     * 环绕通知
     *
     * @param joinPoint 切点
     * @return 切点方法的返回值
     */
    @Around("LogAop.logPointcut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Object result;
        // 这里只能捕获到对应方法内部发生的异常
        // 如果在controller方法上使用注解，是无法捕获到springboot对于参数操作时期发生的异常
        // 无法捕获请求体转json和返回值转json时期的异常
        try {
            result = joinPoint.proceed();
            logMainService.saveNormalLogAsync(joinPoint, result);
        } catch (Throwable throwable) {
            logMainService.saveThrowableLogAsync(joinPoint, throwable);
            // 需要继续抛出异常
            throw throwable;
        }
        return result;
    }

//    @After("LogAop.logPointcut()")
//    public void logAfter(JoinPoint joinPoint) {
//        log.warn("后置通知");
//    }
}
